﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace HFK.DxFluentUI.Utility
{
  public class ChildPropertyDescriptor : PropertyDescriptor
  {
    public ChildPropertyDescriptor(Type type, string path)
      : base(path, null)
    {
      m_syntax = new ChildPropertySyntax(path);
      m_propertList = new Dictionary<string, PropertyDescriptor>();
      for (int i = 0; i < m_syntax.Count; i++ )
      {
        m_propertList.Add(m_syntax.PropertyUntil(i), TypeDescriptor.GetProperties(type)[m_syntax.PropertyParts[i]]);
        type = TypeDescriptor.GetProperties(type)[m_syntax.PropertyParts[i]].PropertyType;
      }
    }

    public override bool IsReadOnly 
    { 
      get 
      {
        return m_propertList[m_syntax.PropertyName].IsReadOnly; 
      } 
    }

    public override string Category 
    { 
      get { return ""; } 
    }

    public override Type PropertyType
    {
      get { return m_propertList[m_syntax.PropertyName].PropertyType; }
    }

    public override Type ComponentType
    {
      get { return m_propertList[m_syntax.PropertyName].ComponentType; }
    }

    public override void ResetValue(object component)
    {
      GetPropertyDescriptorForComponent(ref component).ResetValue(component);
    }

    public override bool CanResetValue(object component)
    {
      return GetPropertyDescriptorForComponent(ref component).CanResetValue(component);
    }

    public override object GetValue(object component)
    {
      return GetPropertyDescriptorForComponent(ref component).GetValue(component);
    }

    public override void SetValue(object component, object value)
    {
      GetPropertyDescriptorForComponent(ref component).SetValue(component, value);
    }

    public override bool ShouldSerializeValue(object component)
    {
      return m_propertList[m_syntax.PropertyName].ShouldSerializeValue(component);
    }

    private ChildPropertySyntax m_syntax;
    private Dictionary<string, PropertyDescriptor> m_propertList;

    private PropertyDescriptor GetPropertyDescriptorForComponent(ref object component)
    { 
      for (int i = 0; i < m_syntax.Count - 1; i++ )
      {
        component = m_propertList[m_syntax.PropertyUntil(i)].GetValue(component);
      }

      return m_propertList[m_syntax.PropertyName];
    }

  }
}
